今天再多補充一個swift聖經裡的重要觀念,防止你記憶體管理不當操成Memory Leak,ARC全名是Automatic Reference Counting,也就是自動化管理記憶體,那swift都幫我們自動化管理了,我們還要做什麼呢?那就是今天要講的東西囉
簡單來說,在正常使用情況下,不需要去思考記憶體管理。當有物件實例化時,swift會幫你在記憶體中劃分一個區塊給他,等到實例化的物件不需要時,會自動幫你釋放記憶體。
下面我們簡單看一下官方範例說明ARC如何work
class Person {
let name: String
init(name: String) { //當初始化物件時,會執裡面的行程式碼
self.name = name
print("\(name) is being initialized")
}
deinit { //當物件消失時,會執行裡面的程式碼
print("\(name) is being deinitialized")
}
}
var tom: Person? = Person(name: "Tom")
// 一個名叫tom的人被創造出來
// print : Tom is initialized
tom = nil
// tom被設成nil,tom所佔的記憶體空間被釋放出來
// print : Tom is deinitialized
所以說,當class物件實例化時,reference count會自動+1,當物件死亡時,reference count就會-1,這就是ARC。
有些情形是物件間相互參考,雖然失去外部參考沒有人可以存取,但記憶體始終不會被釋放。這邊我引用一個網友的筆記文章,很淺顯易懂。
class Person{ //一樣是person的物件
var name : String
var love: Person? //是否有喜歡另一個人
init(name : String) {
self.name = name
print("\(name) is initialized")
}
deinit {
print("\(name) is deinitialized")
}
}
var boy: Person! = Person(name: "Tom") //創造一個男生叫做Tom
var girl: Person! = Person(name: "May") //創造一個女生叫做May
boy.love = girl //Tom喜歡May
girl.love = boy //May也喜歡Tom
boy = nil //男孩失去外部參考,但是因為女孩依然記得他girl.lover = boy,所以reference不會-1
girl = nil //當女孩也失去外部參考,卻因為死去的男孩依然也記得她boy.lover = girl,所以reference count也沒有-1
所以為了解決reference cycle的問題,將有可能造成Reference Cycle的property加上weak關鍵字,跟系統說,這個property不會增加ARC參考數量,注意weak的變數一定要是optional。
把上方的程式碼的love變數前面多加一個weak就可以囉。
weak var love: Person?
這樣雖然兩人相愛boy.love = girl
、girl.love = boy
,但因為weak,所以不會形成相互參考。
使用方式一樣是在property前面加上unowned
關鍵字
簡單講一下weak是用在optional的變數上,unowned是用在非optional的變數上的,但都是為了解決reference count的問題。
所以重點整理weak的變數為optional,被參考的記憶體裡面有沒有東西都可以。unowned的變數為non-optional,被參考的記憶體裡一定有東西,如果沒有東西記憶體會直接釋放unowned變數的空間
如果想更深入研究可以看看我老師的文章